package com.DesignMode.Singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: zjz
 * @Date: 2021/10/09/17:01
 * @Description: private static 以及null才创建,保证单例
 * @Target: 懒汉式单例+双重检测+锁模式
 */
public class DCLLazySingleton {

    private DCLLazySingleton() {
        System.out.println(Thread.currentThread().getName()+"OK");
    }


    // volatile保证不会指令重排
    private static volatile DCLLazySingleton DCLlazySingleton;


    // 双重检测+锁模式
    public static DCLLazySingleton getInstance(){
            if(DCLlazySingleton==null){
                synchronized (DCLLazySingleton.class){
                    if (DCLlazySingleton == null){
                        DCLlazySingleton = new DCLLazySingleton(); // 不是原子性操作
                        /*
                        * 还是会:
                        * 1.分配内存空间
                        * 2.执行构造方法
                        * 3.把这个对象指向这个空间
                        *
                        * */

                    }
                }

            }
            return DCLlazySingleton;
    }



/*
    // test
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                DCLLazySingleton.getInstance();
            }).start();
        }
    }
*/


    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        DCLLazySingleton instance = DCLLazySingleton.getInstance();

        Constructor<DCLLazySingleton> declaredConstructor = DCLLazySingleton.class.getDeclaredConstructor(null);

        declaredConstructor.setAccessible(true);

        DCLLazySingleton instance2 = declaredConstructor.newInstance();

        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());


    }

}
